
// src/composables/CommonScript.ts
import { ref, Ref } from 'vue';
import axios from 'axios';
import { MainAttributeInfoInterface, SearchFormFieldDefinition, RuleItem, Params } from '@/views/common/ts/Interface';
import { ElMessage, ElMessageBox } from "element-plus";
import * as XLSX from 'xlsx';
import { SelectOperation } from "./Interface";

/**
 * 初始化函数，用于访问外部服务进行初始化
 * @returns 返回初始化状态、错误信息和初始化方法
 */
export function useInitialize() {
  const loading = ref(true); // 是否正在加载
  const error = ref<string | null>(null); // 错误信息
  const isInitialized = ref(false); // 是否已初始化

  const executeInitWhenFirstLoaded = async () => {
    if (isInitialized.value) return;
    try {
      // 固定的 API 地址
      const apiUrl = '/mock/api/web-display/main-display/getDisplayInfo';
      const response = await axios.get(apiUrl);

      if (response.data.result !== true) {
        error.value = response.data.msg;
      }

      isInitialized.value = true; // 标记为已初始化
    } catch (err) {
      error.value = (err as Error).message || '未知错误';
    } finally {
      loading.value = false; // 加载完成
    }
  };

  return {
    loading,
    error,
    isInitialized,
    executeInitWhenFirstLoaded,
  };
}




/**
 * 根据查询表单配置生成校验规则
 * @param searchFormConfig 查询表单配置
 * @returns 返回校验规则对象
 */
export const generateRules = (
  searchFormConfig: SearchFormFieldDefinition[]
): Record<string, RuleItem[]> => {
  const rules: Record<string, RuleItem[]> = {};

  searchFormConfig.forEach((field) => {
    if (field.rules) {
      rules[field.queryAttributeName] = field.rules;
    }
  });

  return rules;
};

export interface DetailDialogPropsInterface {
  detailUri: string;
  rowId: string | number;
}


// 添加处理日期范围变化的方法
const upperFirst = (str: string): string =>
  str.charAt(0).toUpperCase() + str.slice(1);

// 修改 handleDateTimeRangeChange 函数
export const handleDateTimeRangeChange = (
  dateRangeTemp: any, // 改为 any 类型，兼容 ref 对象和普通对象
  fieldName: string,
  searchForm: any
) => {
  // 处理 ref 对象的情况：如果包含 value 属性，则访问 value
  const rangeObject = dateRangeTemp && typeof dateRangeTemp === 'object' && 'value' in dateRangeTemp
    ? dateRangeTemp.value
    : dateRangeTemp;

  const rangeValue = rangeObject[fieldName];

  const fieldParts = fieldName.split('.');
  let prefix = '';
  let lastField = '';

  if (fieldParts.length > 1) {
    prefix = fieldParts.slice(0, -1).join('.');
    lastField = fieldParts[fieldParts.length - 1];
  } else {
    lastField = fieldName;
  }

  const capitalizedLastField = upperFirst(lastField);
  const equalAndMoreThanField = prefix
    ? `${prefix}.equalAndMoreThan${capitalizedLastField}`
    : `equalAndMoreThan${capitalizedLastField}`;
  const lessThanField = prefix
    ? `${prefix}.lessThan${capitalizedLastField}`
    : `lessThan${capitalizedLastField}`;

  if (rangeValue && rangeValue.length === 2) {
    searchForm[equalAndMoreThanField] = formatDateTime(rangeValue[0]);
    searchForm[lessThanField] = formatDateTime(rangeValue[1]);
    searchForm[fieldName] = `${formatDateTime(rangeValue[0])},${formatDateTime(rangeValue[1])}`;
  } else {
    searchForm[equalAndMoreThanField] = null;
    searchForm[lessThanField] = null;
    searchForm[fieldName] = null;
  }
};

/**
 * 构建分页相关参数
 * @param params 要添加参数的对象
 * @param pageNum 当前页码
 * @param pageSize 每页条数
 * @param needCountTotal 是否需要计算总数
 */
export const buildPaginationParams = (
  params: Params,
  pageNum: number,
  pageSize: number,
  needCountTotal: boolean,
  queryRequest: string,
) => {
  if (queryRequest != null) {
    // 用变量拼接 key
    const prefix = queryRequest;
    params[`${prefix}.pageNum`] = pageNum;
    params[`${prefix}.pageSize`] = pageSize;
    params[`${prefix}.needCountTotal`] = needCountTotal;
  } else {
    // 没有前缀时直接使用基础 key
    params['pageNum'] = pageNum;
    params['pageSize'] = pageSize;
    params['needCountTotal'] = needCountTotal;
  }
};


export const fetchList = async (
  searchFormRef: any,
  params: Params,
  tableData: Ref<any[]>,
  total: Ref<number>,
  apiUrl: string,
  needCountTotal: boolean,
  searchFormConfig?: SearchFormFieldDefinition[] // 可选的查询字段配置，暂时保留但不使用
) => {
  try {
    // ✅ 校验搜索表单（表单项必须通过校验才继续）
    await searchFormRef.value.validate();

    // ✅ 过滤掉参数中为 null、undefined、空字符串的值，避免发送无效字段
    const filteredParams = Object.keys(params).reduce((acc, key) => {
      const value = params[key];
      if (value !== null && value !== undefined && value !== '') {
        acc[key] = value;
      }
      return acc;
    }, {} as Record<string, any>);

    const requestPayload: Record<string, any> = buildNestedPayload(filteredParams);

    // ✅ 发送 POST 请求
    const response = await axios.post(apiUrl, requestPayload);

    // ✅ 处理返回数据
    if (response.data.result) {
      tableData.value = response.data.data;
      // 可选统计总条数
      if (needCountTotal) {
        total.value = response.data.totalCount;
      }
    } else {
      // 提示错误信息（优先使用服务端 msg 字段）
      ElMessage.warning(response.data.msg ?? "查询异常");
    }
  } catch (error) {
    console.error('请求失败', error);
  }
};

/**
 * 将带有"."的扁平参数键转换为嵌套对象结构
 * @param params 扁平的参数对象
 * @returns 转换后的嵌套对象
 */
export function buildNestedPayload(params: Record<string, any>): Record<string, any> {
  const result: Record<string, any> = {};

  for (const key of Object.keys(params)) {
    const value = params[key];
    if (key.includes('.')) {
      const parts = key.split('.');
      let current = result;
      for (let i = 0; i < parts.length; i++) {
        const part = parts[i];
        if (i === parts.length - 1) {
          current[part] = value;
        } else {
          if (!current[part]) {
            current[part] = {};
          }
          current = current[part];
        }
      }
    } else {
      result[key] = value;
    }
  }

  return result;
}


/**
 * 获取属性名称与展示名称的映射（仅包含可见列）
 * @param tableColumnList 表格列配置列表（包含 attributeName 和 attributeLabel 字段）
 * @returns 属性名到展示名的映射对象，仅包含未被默认隐藏的列
 */
export const buildVisableAttributeLabelList = (
  tableColumnList: MainAttributeInfoInterface[]
): Array<Record<string, string>> => {
  return tableColumnList
    .filter(column => !column.isDefaultHidden)
    .map(column => ({
      [column.attributeName]: column.attributeLabel,
    }));
};

/**
 * 获取默认可见的列名列表
 * @param tableColumnList 表格列配置列表
 * @returns 默认可见的列名数组
 */
export const getVisibleColumnList = (tableColumnList: MainAttributeInfoInterface[]): string[] => {
  return tableColumnList
    .filter(
      (column) =>
        !column.isDefaultHidden || (column.extendsAttributeInfo != null && column.extendsAttributeInfo.showRequired)
    )
    .map((column) => column.attributeName);
};


/**
 * 获取当前需要显示的列配置
 * @param tableColumnList 表格列配置列表
 * @param visibleColumnList 当前可见的列名列表
 * @returns 当前需要显示的列配置数组
 */
export const updateCurrentShowColumnListByVisibleList = (
  tableColumnList: MainAttributeInfoInterface[],
  visibleColumnList: string[]
): MainAttributeInfoInterface[] => {
  return tableColumnList.filter((column) =>
    visibleColumnList.includes(column.attributeName)
  );
};


/**
 * 批量删除
 * @param selectedRows - 选中的行数据
 * @param tableData - 表格数据
 * @param idKey - 行的唯一标识字段（如 "address"）
 * @param url - 删除请求的接口地址
 */
export const handleBatchDelete = async <T extends Record<string, any>>(
  selectedRows: T[],
  tableData: Ref<T[]>,
  idKey: string,
  totalRef: Ref<number>,
  url: string
): Promise<void> => {
  if (selectedRows.length === 0) {
    ElMessage.warning("请选择要删除的数据");
    return;
  }

  try {
    // 确认删除
    await ElMessageBox.confirm("确定要删除选中的数据吗？", "提示", {
      type: "warning",
    });

    // 获取选中行的 ID 列表
    const ids = selectedRows.map((row) => getNestedValue(row, idKey));
    // 发送删除请求，直接将 ids 数组作为请求体
    const response = await axios.post(url, ids);

    if (response.data.result) {
      ElMessage.success("删除成功");
      // 直接删除当前页面数据
      tableData.value = tableData.value.filter(
        (row) => !ids.includes(getNestedValue(row, idKey))
      );
      // 更新总记录数
      totalRef.value = totalRef.value - selectedRows.length;
    } else {
      if (response.data.msg != null) {
        ElMessage.error(response.data.msg);
      } else {
        ElMessage.error("删除失败");
      }
    }
  } catch (err) {
    console.error("删除失败", err);
  }
};

// 提取快捷选项为单独变量
export const dateRangeShortcuts = [
  {
    text: '截至今日',
    value: () => {
      const end = new Date();
      end.setDate(end.getDate() + 1);
      end.setHours(0, 0, 0, 0);
      const start = new Date(0);
      return [start, end];
    },
  },
  {
    text: '截至昨日',
    value: () => {
      const end = new Date();
      end.setHours(0, 0, 0, 0);
      const start = new Date(0);
      return [start, end];
    },
  },
  {
    text: '本周',
    value: () => {
      const now = new Date();
      const day = now.getDay();
      const start = new Date(now);
      start.setDate(now.getDate() - (day === 0 ? 6 : day - 1));
      start.setHours(0, 0, 0, 0);
      const end = new Date(start);
      end.setDate(start.getDate() + 7);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '上周',
    value: () => {
      const now = new Date();
      const day = now.getDay();
      const start = new Date(now);
      start.setDate(now.getDate() - (day === 0 ? 6 : day - 1) - 7);
      start.setHours(0, 0, 0, 0);
      const end = new Date(start);
      end.setDate(start.getDate() + 7);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '下周',
    value: () => {
      const now = new Date();
      const day = now.getDay();
      const start = new Date(now);
      start.setDate(now.getDate() - (day === 0 ? 6 : day - 1) + 7);
      start.setHours(0, 0, 0, 0);
      const end = new Date(start);
      end.setDate(start.getDate() + 7);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '本月',
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), now.getMonth(), 1);
      start.setHours(0, 0, 0, 0);
      const end = new Date(now.getFullYear(), now.getMonth() + 1, 1);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '上月',
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), now.getMonth() - 1, 1);
      start.setHours(0, 0, 0, 0);
      const end = new Date(now.getFullYear(), now.getMonth(), 1);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '下月',
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), now.getMonth() + 1, 1);
      start.setHours(0, 0, 0, 0);
      const end = new Date(now.getFullYear(), now.getMonth() + 2, 1);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '本季度',
    value: () => {
      const now = new Date();
      const quarter = Math.floor(now.getMonth() / 3);
      const start = new Date(now.getFullYear(), quarter * 3, 1);
      start.setHours(0, 0, 0, 0);
      const end = new Date(now.getFullYear(), quarter * 3 + 3, 1);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '上半年',
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), 0, 1);
      start.setHours(0, 0, 0, 0);
      const end = new Date(now.getFullYear(), 6, 1);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '下半年',
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), 6, 1);
      start.setHours(0, 0, 0, 0);
      const end = new Date(now.getFullYear() + 1, 0, 1);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '本年-今日',
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), 0, 1);
      start.setHours(0, 0, 0, 0);
      const end = new Date(now);
      end.setDate(end.getDate() + 1);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '本年-昨日',
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), 0, 1);
      start.setHours(0, 0, 0, 0);
      const end = new Date(now);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '本年-年底',
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), 0, 1);
      start.setHours(0, 0, 0, 0);
      const end = new Date(now.getFullYear() + 1, 0, 1);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
  {
    text: '去年',
    value: () => {
      const now = new Date();
      const lastYear = now.getFullYear() - 1;
      const start = new Date(lastYear, 0, 1);
      start.setHours(0, 0, 0, 0);
      const end = new Date(now.getFullYear(), 0, 1);
      end.setHours(0, 0, 0, 0);
      return [start, end];
    },
  },
];


/**
 * 根据路径获取嵌套对象的值
 * @param obj 源对象
 * @param path 属性路径，如 'a.b.c'
 * @returns 属性值或 null
 */
// 移除了 async 关键字
export const getNestedValue = (obj: Record<string, any>, path: string): any => {
  if (!obj || !path) return null;
  return path.split('.').reduce((acc, key) => {
    if (acc && Object.prototype.hasOwnProperty.call(acc, key)) {
      return acc[key];
    }
    return null;
  }, obj);
};


export const handleCommonDownload = async (
  params: Record<string, any>, // 键是 string，值是任意类型,
  url: string
): Promise<void> => {

  params.pageSize = 10000000;
  params.needCountTotal = true;
  params.pageNum = 1;
  const response = await fetch(
    url,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(params),
    }
  );

  if (!response.ok) {
    throw new Error(`HTTP 错误！状态码: ${response.status}`);
  }

  // 首先检查响应内容类型
  const contentType = response.headers.get("content-type");
  if (
    contentType &&
    (contentType.includes("application/json") ||
      contentType.includes("text/plain"))
  ) {
    // 处理JSON响应（错误情况）
    const errorData = await response.json();
    ElMessage.error(errorData.msg || "下载失败");
    return;
  } else {
    // 获取二进制数据
    const blob = await response.blob();

    // 解析 Content-Disposition 头部获取文件名
    const contentDisposition = response.headers.get("content-disposition");
    let fileName = "data.xlsx";
    if (contentDisposition) {
      const fileNameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/i;
      const matches = fileNameRegex.exec(contentDisposition);
      if (matches && matches[1]) {
        fileName = decodeURIComponent(matches[1].replace(/['"]/g, ""));
      }
    }
    // 创建下载链接
    const downloadUrl = window.URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = downloadUrl;
    link.download = fileName; // 解析后的文件名
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(downloadUrl);
  }
}

// CommonFunction.ts
// 用于表格中把下拉的value转成label显示（比如F→女，M→男）
export const formatSelectLabel = (row: any, column: any) => {
  // 从列配置里拿到下拉选项（比如[{value:'F',label:'女'},...]）
  const options = column.selectOperation?.options || [];
  // 从行数据里拿到当前字段的值（比如row.userSex是'F'）
  const fieldValue = row[column.attributeName];
  // 找到对应的选项，返回label，找不到就返回原值
  const matchOption = options.find((opt: any) => opt.value === fieldValue);
  return matchOption ? matchOption.label : fieldValue || '';
};

export const handleCurrentPageDownload = (
  tableData: any[],
  columns: MainAttributeInfoInterface[],
  searchParams: Record<string, any>,
  pagination: { currentPage: number; pageSize: number; total: number },
  fileName: string = 'data'
): boolean => {
  try {
    // 创建工作簿
    const wb = XLSX.utils.book_new();

    // ========== Sheet1: 数据 ==========
    const wsData = XLSX.utils.json_to_sheet([]);

    // 准备表头数据
    const headerEn = ['No.'];
    const headerCn = ['序号'];
    const attributeNames = ['index'];

    columns.forEach(column => {
      headerEn.push(column.attributeName);
      headerCn.push(column.attributeLabel);
      attributeNames.push(column.attributeName);
    });

    // 互换第一行和第二行，先添加中文表头
    XLSX.utils.sheet_add_aoa(wsData, [headerCn, headerEn], { origin: 'A1' });

    // 填充数据
    const data = tableData.map((row, index) => {
      const rowData: any = { index: index + 1 };
      columns.forEach(column => {
        rowData[column.attributeName] = row[column.attributeName] || '';
      });
      return rowData;
    });

    XLSX.utils.sheet_add_json(wsData, data, {
      header: attributeNames,
      skipHeader: true,
      origin: 'A3'
    });

    // ========== Sheet2: 查询条件 ==========
    const wsParams = XLSX.utils.json_to_sheet([]);

    // 准备查询条件表头
    const paramsHeader = ['序号', ...Object.keys(searchParams), 'pageNum', 'pageSize', 'orderByClause', 'needCountTotal', '总记录数'];
    // 准备查询条件数据
    const paramsRow = ['query-1', ...Object.values(searchParams), pagination.currentPage, pagination.pageSize, '', false, pagination.total];

    // 添加表头
    XLSX.utils.sheet_add_aoa(wsParams, [paramsHeader], { origin: 'A1' });
    // 添加数据行
    XLSX.utils.sheet_add_aoa(wsParams, [paramsRow], { origin: 'A2' });

    // 添加工作表到工作簿
    XLSX.utils.book_append_sheet(wb, wsData, 'query-1');
    XLSX.utils.book_append_sheet(wb, wsParams, 'DownloadQuery');

    // 生成并下载文件
    const dateStr = new Date().toISOString().slice(0, 10);
    XLSX.writeFile(wb, `${fileName}_${dateStr}.xlsx`);

    return true;
  } catch (error) {
    console.error('导出当前页数据失败:', error);
    return false;
  }
};



// 日期时间格式化函数
export const formatDateTime = (date: Date | string | null): string | null => {
  if (!date) return null;

  // 如果已经是字符串格式，直接返回
  if (typeof date === 'string') return date;

  // 处理Date对象
  const pad = (num: number) => num.toString().padStart(2, '0');
  const year = date.getFullYear();
  const month = pad(date.getMonth() + 1);
  const day = pad(date.getDate());
  const hours = pad(date.getHours());
  const minutes = pad(date.getMinutes());
  const seconds = pad(date.getSeconds());

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};


/**
 * 文件上传前的校验函数（Excel文件专用）
 * @param {File} file - 待上传的文件对象
 * @param {number} maxSizeMB - 文件允许的最大体积（单位：MB）
 * @returns {boolean} - 校验结果：true表示通过校验，false表示校验失败
 * @description 校验规则：1. 文件格式必须为.xlsx；2. 文件大小不超过指定的maxSizeMB
 */
export const beforeUpload = (file: File, maxSizeMB: number) => {
  // 检查文件后缀名（忽略大小写）
  const isXLSX = file.name.toLowerCase().endsWith('.xlsx')

  if (!isXLSX) {
    ElMessage.error('只能上传 .xlsx 格式的 Excel 文件!')
    return false
  }

  if (maxSizeMB == 0 || maxSizeMB <= 0) {
    maxSizeMB = 5
  }

  // 转换文件大小单位（Byte → MB）并校验
  const isLtMaxSize = file.size / 1024 / 1024 < maxSizeMB
  if (!isLtMaxSize) {
    ElMessage.error(`文件大小不能超过 ${maxSizeMB}MB!`)
    return false
  }
  return true
}

export const customUploadRequest = async (options: any, entityName:string, uploadUrl:string) => {
  const formData = new FormData()
  formData.append('file', options.file)
  formData.append('entityName', entityName);

  try {
    const res = await fetch(uploadUrl, {
      method: 'POST',
      body: formData,
    })

    const json = await res.json()
    if(json.result){
      ElMessage.success(json.msg);
      options.onSuccess(json); // 通知组件上传成功
    }else{
      ElMessage.error(json.msg);
      options.onError(json); // 通知组件上传失败
    }
  } catch (err) {
    console.error("上传失败:", err);
    ElMessage.error('上传失败，请重试');
    options.onError(err); // 通知组件上传异常
  }
}

/**
 * Select列专用格式化函数（仅用于editType='select'的列）
 * @param row 表格行数据
 * @param column 当前列的完整配置（含selectOperation）
 * @returns 转换后的label（支持单选/多选）
 */
export function selectColumnFormatter(
  row: any,
  column: MainAttributeInfoInterface
): string {
  // 1. 从列配置中获取字段名和下拉配置
  const { attributeName, selectOperation } = column;
  // 2. 获取当前行的原始值
  const value = row[attributeName];

  // 异常防护：无下拉配置或无值时返回原值
  if (!selectOperation?.options || value === undefined || value === null) {
    return value;
  }

  // 3. 处理多选场景（值为数组）
  if (Array.isArray(value)) {
    return value
      .map((v) => selectOperation.options.find((item) => item.value === v)?.label || v)
      .join(", ");
  }

  // 4. 处理单选场景
  return selectOperation.options.find((item) => item.value === value)?.label || value;
}